﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web;
using System.Web.Compilation;
using Vit.Web.Models;
using Vit.Web.Services;

namespace Vit.Web.Mvc
{
    public class SiteRouteHandler : MvcRouteHandler
    {
        private const string RoutingUrlPattern = @"([^\.]+\.(aspx|html|htm))|(^[^\.]+$)";

        #region IRouteHandler Members

        protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            WebSite site = ((Vit.Web.VitApplication)HttpContext.Current.ApplicationInstance).CurrentSite;
            if (site != null)
            {
                site.RouteData = requestContext.RouteData;
                if (!PageLoaded && Regex.IsMatch(requestContext.HttpContext.Request.Url.OriginalString, RoutingUrlPattern))
                {
                    WebPage wpage = new WebPage();
                    wpage.WebSite = site;
                    if (requestContext.HttpContext.Request.QueryString["dialog"] != null)
                    {
                        wpage = site.DialogPage;
                    }
                    else
                    {
                        if (requestContext.HttpContext.Request.Path == requestContext.HttpContext.Request.ApplicationPath)
                        {
                            wpage = site.HomePage;
                        }
                        else if (requestContext.HttpContext.Request.Path.IndexOf(".") < 0)
                        {
                            string areaName = requestContext.RouteData.DataTokens["area"] as string ?? "";
                            string controllerName = requestContext.RouteData.GetRequiredString("controller");
                            string actionName = requestContext.RouteData.GetRequiredString("action");
                            if (areaName.ToLower() == "main")
                                areaName = "";

                            wpage.Name = string.Format("{0}/{1}/{2}", areaName, controllerName, actionName);
                            wpage.Path = string.Format("{0}/Pages/{1}.aspx", site.RootPath, wpage.Name);
                        }
                        else
                        {
                            wpage.Name = requestContext.HttpContext.Request.Path.TrimStart('/').Replace(".aspx", "");
                            wpage.Path = string.Format("{0}/Pages/{1}.aspx", site.RootPath, wpage.Name);
                        }
                    }

                    string file = requestContext.HttpContext.Server.MapPath(wpage.Path);
                    if (!File.Exists(file))
                    {
                        wpage = site.MissingPage;
                        file = requestContext.HttpContext.Server.MapPath(wpage.Path);
                    }
                    if (File.Exists(file))
                    {
                        ViewPage page = BuildManager.CreateInstanceFromVirtualPath(wpage.Path, typeof(ViewPage)) as ViewPage;
                        ControllerContext controllerContext = new ControllerContext(requestContext, new PageHandlerController());
                        WebFormView view = new WebFormView(wpage.Path);
                        ViewDataDictionary viewData = new ViewDataDictionary();
                        TempDataDictionary tempData = new TempDataDictionary();
                        page.ViewContext = new ViewContext(controllerContext, view, viewData, tempData);

                        // set menu
                        requestContext.HttpContext.Items["page"] = wpage;

                        PageLoaded = true;
                        return page;
                    }
                }
            }
            return base.GetHttpHandler(requestContext);
        }

        #endregion

        private bool PageLoaded
        {
            get
            {
                return HttpContext.Current.Items["PageLoaded"] != null;
            }
            set
            {
                if (value == false)
                    HttpContext.Current.Items.Remove("PageLoaded");
                HttpContext.Current.Items["PageLoaded"] = true;
            }
        }
    }
}
